if (window.crPriceTickerWidget === undefined) {
    window.crPriceTickerWidget = {};
    window.crPriceTickerWidget.elClass = 'cr-price-ticker-widget';

    window.crPriceTickerWidget.install = () => {
        docReady(function () {
            var elements = document.getElementsByClassName(window.crPriceTickerWidget.elClass);
            window.crPriceTickerWidget.loadWidgets(elements);
        });
    };

    window.crPriceTickerWidget.loadWidgets = (elements, elementIndex) => {
        var elementIndex = elementIndex || 0;
        var element = elements[elementIndex];
        if (elementIndex <= elements.length - 1) {
            window.crPriceTickerWidget.load(element, () => {
                window.crPriceTickerWidget.loadWidgets(elements, elementIndex + 1);
            });
        }
    };

    window.crPriceTickerWidget.load = (element, next) => {
        if (!element.dataset.apiUrl || !element.dataset.siteUrl) {
            console.warn('API URL and Site URL for the widget are not set, please update the script initialization code');
        }

        window.crPriceTickerWidget.apiUrl = element.dataset.apiUrl || 'https://api.cryptorank.io/v0';
        window.crPriceTickerWidget.siteUrl = element.dataset.siteUrl || 'https://cryptorank.io';
        var coinKey = element.dataset.coinKey;
        var baseKey = element.dataset.baseKey;
        var secondaryKey = element.dataset.secondaryKey;
        var convertToBase = element.dataset.statKey === baseKey;

        var params = {
            baseKey: baseKey,
            secondaryKey: secondaryKey,
            convertToBase: convertToBase,
        };

        window.getRequest(`${window.crPriceTickerWidget.apiUrl}/widget/price-ticker/${coinKey}`, params, (data) => {
            window.crPriceTickerWidget.renderHtml(element, data.data);
            if (next) {
                next();
            }
        });
    };

    window.getRequest = (url, params, success) => {
        var queryParams = [];
        for (var field in params) {
            queryParams.push(`${field}=${params[field]}`);
        }

        var getUrl = url;
        if (queryParams.length) {
            getUrl += `?${queryParams.join('&')}`;
        }

        var oReq = new XMLHttpRequest();
        oReq.open('GET', getUrl);
        oReq.send();
        oReq.onload = function () {
            var json = JSON.parse(oReq.response);
            if (typeof success === 'function') {
                success(json);
            }
        };
    };

    window.crPriceTickerWidget.getAvailableValue = (availableValues, value, defaultValue) => {
        if (availableValues.indexOf(value) >= 0) {
            return value;
        } else {
            return defaultValue;
        }
    };

    window.crPriceTickerWidget.renderHtml = (element, data) => {
        var showPrimaryTicker = element.dataset.ticker === 'true';
        var showRank = element.dataset.rank === 'true';
        var showMarketCap = element.dataset.marketCap === 'true';
        var showVolume = element.dataset.volume === 'true';
        var showStatSymbol = element.dataset.stats === 'true';

        var getColCount = function () {
            var count = 0;
            var showCols = [showRank, showMarketCap, showVolume];
            for (var i = 0; i < showCols.length; ++i) {
                if (showCols[i] === true) {
                    count++;
                }
            }
            return count;
        };

        var calcColWidth = function () {
            var count = getColCount();
            switch (count) {
                case 1:
                    return 100;
                case 2:
                    return 49.8;
                case 3:
                    return 33;
                default:
                    return 0;
            }
        };
        var changeColor = data.changePercent ? (data.changePercent > 0 ? 'rgb(0, 212, 164)' : 'rgb(255, 89, 149)') : '';
        var colWidth = calcColWidth();
        var colCount = getColCount();
        var firstColBorder = colCount === 2 || colCount === 3 ? 'border-right:1px solid #e1e5ea;' : '';
        var secondColBorder = (colCount === 2 && !showRank) || colCount === 3 ? 'border-right:1px solid #e1e5ea;' : '';

        var html = `<div style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif" class="h-screen w-screen">
          <div>
            <div style='float:right;width:67%;border: none;text-align:left;padding:5px 0px;line-height:30px;'>
              <span style='font-size: 18px;'>
                <a href='${window.crPriceTickerWidget.siteUrl}/price/${
            data.key
        }' target='_blank' style='text-decoration: none; color: #0079fb'>
                  ${data.name}${showPrimaryTicker ? ` (${data.symbol})` : ''}
                </a>
              </span>
              <br>
              <span style='font-size: 16px;'>
                ${data.price}
                ${
            data.changePercent
                ? `<span style='color:${changeColor}'>(${data.changePercent.toFixed(2)}%)</span>`
                : ''
        }
              </span>
              ${
            data.secondaryPrice
                ? `<br><span style='font-size: 12px; color: rgba(39, 52, 64, 0.5)'>${data.secondaryPrice}</span>`
                : ''
        }
            </div>
          </div>
          ${
            colWidth !== 0
                ? `<div style='border-top: 1px solid #e1e5ea;clear:both;'>
            ${
                    showRank
                        ? `<div style='text-align:center;float:left;width:${colWidth}%;font-size:12px;padding:12px 0;line-height:1.4em;${firstColBorder}'>
              RANK<br><br>
              <span style='font-size: 17px;'>${data.rank || 'N/A'}</span>
            </div>`
                        : ''
                }
            ${
                    showMarketCap
                        ? `<div style='text-align:center;float:left;width:${colWidth}%;font-size:12px;padding:12px 0 16px 0;line-height:1.3em;${secondColBorder}'>
              MARKET CAP<br><br>
              <span style='font-size: 14px;'>
                ${data.marketCap}
                ${showStatSymbol ? `<span style='font-size:9px'>${data.statSymbol}</span>` : ''}
              </span>
            </div>`
                        : ''
                }
            ${
                    showVolume
                        ? `<div style='text-align:center;float:left;width:${colWidth}%;font-size:12px;padding:12px 0 16px 0;line-height:1.3em;'>
              VOLUME<br><br>
              <span style='font-size: 14px;'>
                ${data.volume}
                ${showStatSymbol ? `<span style='font-size:9px'>${data.statSymbol}</span>` : ''}
              </span>
            </div>`
                        : ''
                }
          </div>`
                : ''
        }
          <div style='border-top: 1px solid #e1e5ea;text-align:center;clear:both;font-size:10px;font-style:italic;padding:5px 0;'>
            <a href='${
            window.crPriceTickerWidget.siteUrl
        }' target='_blank' style='text-decoration: none; color: #0079fb'>Powered by CryptoRank.io</a>
          </div>
      </div>`;

        element.innerHTML = html;
    };

    (function (funcName, baseObj) {
        funcName = funcName || 'docReady';
        baseObj = baseObj || window;
        let readyList = [];
        let readyFired = false;
        let readyEventHandlersInstalled = false;

        function ready() {
            if (!readyFired) {
                readyFired = true;
                for (let i = 0; i < readyList.length; i++) {
                    readyList[i].fn.call(window, readyList[i].ctx);
                }
                readyList = [];
            }
        }

        function readyStateChange() {
            if (document.readyState === 'complete') {
                ready();
            }
        }

        baseObj[funcName] = function (callback, context) {
            if (typeof callback !== 'function') {
                throw new TypeError('callback for docReady(fn) must be a function');
            }

            if (readyFired) {
                setTimeout(function () {
                    callback(context);
                }, 1);
                return;
            } else {
                readyList.push({ fn: callback, ctx: context });
            }

            if (document.readyState === 'complete' || (!document.attachEvent && document.readyState === 'interactive')) {
                setTimeout(ready, 1);
            } else if (!readyEventHandlersInstalled) {
                if (document.addEventListener) {
                    document.addEventListener('DOMContentLoaded', ready, false);
                    window.addEventListener('load', ready, false);
                } else {
                    document.attachEvent('onreadystatechange', readyStateChange);
                    window.attachEvent('onload', ready);
                }
                readyEventHandlersInstalled = true;
            }
        };
    })('docReady', window);

    window.crPriceTickerWidget.install();
}